package book

import (
	"context"
	"time"

	"BookStack/internal/domain/events"
	appErrors "BookStack/pkg/errors"
	"BookStack/pkg/utils"
)

// 创建章节
func (s *service) CreateChapter(ctx context.Context, req *CreateChapterRequest) (*ChapterResponse, error) {
	// 检查书籍是否存在
	_, err := s.bookService.GetBookByID(ctx, req.BookID)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeBookNotFound {
			return nil, BookNotFound(req.BookID)
		}
		return nil, DatabaseError(err)
	}

	// 调用领域服务创建章节
	chapter, err := s.bookService.CreateChapter(
		ctx,
		req.BookID,
		req.Title,
		req.Slug,
		req.Content,
		req.Sort,
		req.CreatedBy,
	)

	// 处理错误
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok {
			switch appErr.Code {
			case appErrors.ErrCodeChapterTitleRequired:
				return nil, ChapterTitleRequired()
			case appErrors.ErrCodeChapterContentRequired:
				return nil, ChapterContentRequired()
			case appErrors.ErrCodeChapterBookIDRequired:
				return nil, ChapterBookIDRequired()
			case appErrors.ErrCodeChapterSlugExists:
				return nil, ChapterSlugExists(req.Slug)
			default:
				return nil, DatabaseError(err)
			}
		}
		return nil, DatabaseError(err)
	}

	// 发布章节创建事件
	event := &events.ChapterCreatedEvent{
		ID:        chapter.ID,
		BookID:    chapter.BookID,
		Title:     chapter.Title,
		CreatedBy: chapter.CreatedBy,
		CreatedAt: utils.TimeToJSONTime(chapter.CreatedAt),
	}

	// 异步发布事件
	s.eventPublisher.AsyncPublish(ctx, events.NewEvent(events.ChapterCreatedEventType, event))

	// 转换为响应DTO
	return ChapterToResponse(chapter), nil
}

// 通过ID获取章节
func (s *service) GetChapterByID(ctx context.Context, id uint) (*ChapterResponse, error) {
	// 调用领域服务获取章节
	chapter, err := s.bookService.GetChapterByID(ctx, id)

	// 处理错误
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeChapterNotFound {
			return nil, ChapterNotFound(id)
		}
		return nil, DatabaseError(err)
	}

	// 转换为响应DTO
	return ChapterToResponse(chapter), nil
}

// 更新章节
func (s *service) UpdateChapter(ctx context.Context, id uint, req *UpdateChapterRequest, updatedBy uint) (*ChapterResponse, error) {
	// 检查章节是否存在
	existingChapter, err := s.bookService.GetChapterByID(ctx, id)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeChapterNotFound {
			return nil, ChapterNotFound(id)
		}
		return nil, DatabaseError(err)
	}

	// 检查书籍是否存在
	_, err = s.bookService.GetBookByID(ctx, existingChapter.BookID)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeBookNotFound {
			return nil, BookNotFound(existingChapter.BookID)
		}
		return nil, DatabaseError(err)
	}

	// 调用领域服务更新章节
	chapter, err := s.bookService.UpdateChapter(
		ctx,
		id,
		req.Title,
		req.Content,
		updatedBy,
	)

	// 处理错误
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok {
			switch appErr.Code {
			case appErrors.ErrCodeChapterNotFound:
				return nil, ChapterNotFound(id)
			case appErrors.ErrCodeChapterTitleRequired:
				return nil, ChapterTitleRequired()
			case appErrors.ErrCodeChapterContentRequired:
				return nil, ChapterContentRequired()
			default:
				return nil, DatabaseError(err)
			}
		}
		return nil, DatabaseError(err)
	}

	// 发布章节更新事件
	event := &events.ChapterUpdatedEvent{
		ID:        chapter.ID,
		BookID:    chapter.BookID,
		Title:     chapter.Title,
		UpdatedBy: updatedBy,
		UpdatedAt: utils.TimeToJSONTime(chapter.UpdatedAt),
	}

	// 异步发布事件
	s.eventPublisher.AsyncPublish(ctx, events.NewEvent(events.ChapterUpdatedEventType, event))

	// 转换为响应DTO
	return ChapterToResponse(chapter), nil
}

// 删除章节（移入回收站）
func (s *service) DeleteChapter(ctx context.Context, id uint, deletedBy uint) error {
	// 首先获取章节信息，用于事件发布
	chapter, err := s.bookService.GetChapterByID(ctx, id)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeChapterNotFound {
			return ChapterNotFound(id)
		}
		return DatabaseError(err)
	}

	// 获取书籍信息，用于事件发布
	_, err = s.bookService.GetBookByID(ctx, chapter.BookID)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeBookNotFound {
			return BookNotFound(chapter.BookID)
		}
		return DatabaseError(err)
	}

	// 调用领域服务删除章节
	err = s.bookService.DeleteChapter(ctx, id, deletedBy)
	if err != nil {
		return DatabaseError(err)
	}

	// 发布章节删除事件
	event := &events.ChapterDeletedEvent{
		ID:        chapter.ID,
		BookID:    chapter.BookID,
		Title:     chapter.Title,
		DeletedBy: deletedBy,
		DeletedAt: utils.TimeToJSONTime(time.Now()),
	}

	// 异步发布事件
	s.eventPublisher.AsyncPublish(ctx, events.NewEvent(events.ChapterDeletedEventType, event))

	return nil
}

// 获取书籍下的章节列表
func (s *service) ListChaptersByBookID(ctx context.Context, bookID uint) ([]*ChapterResponse, error) {
	// 检查书籍是否存在
	_, err := s.bookService.GetBookByID(ctx, bookID)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeBookNotFound {
			return nil, BookNotFound(bookID)
		}
		return nil, DatabaseError(err)
	}

	// 调用领域服务获取章节列表
	chapters, _, err := s.bookService.ListChaptersByBookID(ctx, bookID, 0, 1000)

	// 处理错误
	if err != nil {
		return nil, DatabaseError(err)
	}

	// 转换为响应DTO
	chapterResponses := make([]*ChapterResponse, 0, len(chapters))
	for _, chapter := range chapters {
		chapterResponses = append(chapterResponses, ChapterToResponse(chapter))
	}

	return chapterResponses, nil
}

// 重排章节顺序
func (s *service) ReorderChapters(ctx context.Context, req *ChapterReorderRequest, updatedBy uint) error {
	// 检查书籍是否存在
	_, err := s.bookService.GetBookByID(ctx, req.BookID)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeBookNotFound {
			return BookNotFound(req.BookID)
		}
		return DatabaseError(err)
	}

	// 检查所有章节ID是否存在
	chapterIDs := make([]uint, 0, len(req.ChapterOrders))
	for _, order := range req.ChapterOrders {
		chapterIDs = append(chapterIDs, order.ID)
	}

	// 构建排序数据
	orders := make(map[uint]int, len(req.ChapterOrders))
	for _, order := range req.ChapterOrders {
		orders[order.ID] = order.Sort
	}

	// 调用领域服务重排章节
	err = s.bookService.ReorderChapters(ctx, req.BookID, orders, updatedBy)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeChapterNotBelongToBook {
			return ChapterNotBelongToBook(chapterIDs, req.BookID)
		}
		return DatabaseError(err)
	}

	// 发布章节重排事件
	event := &events.ChapterReorderedEvent{
		BookID:      req.BookID,
		ReorderedBy: updatedBy,
		ReorderedAt: utils.TimeToJSONTime(time.Now()),
	}

	// 异步发布事件
	s.eventPublisher.AsyncPublish(ctx, events.NewEvent(events.ChapterReorderedEventType, event))

	return nil
}

// 获取前一章节
func (s *service) GetPrevChapter(ctx context.Context, chapterID uint) (*ChapterResponse, error) {
	// 首先获取当前章节信息
	currentChapter, err := s.bookService.GetChapterByID(ctx, chapterID)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeChapterNotFound {
			return nil, ChapterNotFound(chapterID)
		}
		return nil, DatabaseError(err)
	}

	// 调用领域服务获取上一章节
	prevChapter, err := s.bookService.GetPrevChapter(ctx, currentChapter.BookID, currentChapter.Order)

	// 如果没有上一章，返回nil，不是错误
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeChapterNotFound {
			return nil, nil
		}
		return nil, DatabaseError(err)
	}

	// 转换为响应DTO
	return ChapterToResponse(prevChapter), nil
}

// 获取后一章节
func (s *service) GetNextChapter(ctx context.Context, chapterID uint) (*ChapterResponse, error) {
	// 首先获取当前章节信息
	currentChapter, err := s.bookService.GetChapterByID(ctx, chapterID)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeChapterNotFound {
			return nil, ChapterNotFound(chapterID)
		}
		return nil, DatabaseError(err)
	}

	// 调用领域服务获取下一章节
	nextChapter, err := s.bookService.GetNextChapter(ctx, currentChapter.BookID, currentChapter.Order)

	// 如果没有下一章，返回nil，不是错误
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeChapterNotFound {
			return nil, nil
		}
		return nil, DatabaseError(err)
	}

	// 转换为响应DTO
	return ChapterToResponse(nextChapter), nil
}

// 在书籍内搜索章节
func (s *service) SearchChaptersInBook(ctx context.Context, bookID uint, keyword string, page, pageSize int) ([]*ChapterResponse, int64, error) {
	// 检查书籍是否存在
	_, err := s.bookService.GetBookByID(ctx, bookID)
	if err != nil {
		appErr, ok := err.(appErrors.AppError)
		if ok && appErr.Code == appErrors.ErrCodeBookNotFound {
			return nil, 0, BookNotFound(bookID)
		}
		return nil, 0, DatabaseError(err)
	}

	// 默认分页参数
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 20
	}

	// 计算偏移量
	offset := (page - 1) * pageSize

	// 调用领域服务搜索章节
	chapters, total, err := s.bookService.SearchChaptersInBook(ctx, bookID, keyword, offset, pageSize)

	// 处理错误
	if err != nil {
		return nil, 0, DatabaseError(err)
	}

	// 转换为响应DTO
	chapterResponses := make([]*ChapterResponse, 0, len(chapters))
	for _, chapter := range chapters {
		chapterResponses = append(chapterResponses, ChapterToResponse(chapter))
	}

	return chapterResponses, total, nil
}
